#ifndef __GSOCKET_H
#define __GSOCKET_H

#ifndef __GSOCKET_STANDALONE__
#include "wx/defs.h"

#endif

#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)

#include <stddef.h>
#include <sys/types.h>


class GSocket;

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _GAddress GAddress;

typedef enum {
  GSOCK_NOFAMILY = 0,
  GSOCK_INET,
  GSOCK_INET6,
  GSOCK_UNIX
} GAddressType;

typedef enum {
  GSOCK_STREAMED,
  GSOCK_UNSTREAMED
} GSocketStream;

typedef enum {
  GSOCK_NOERROR = 0,
  GSOCK_INVOP,
  GSOCK_IOERR,
  GSOCK_INVADDR,
  GSOCK_INVSOCK,
  GSOCK_NOHOST,
  GSOCK_INVPORT,
  GSOCK_WOULDBLOCK,
  GSOCK_TIMEDOUT,
  GSOCK_MEMERR,
  GSOCK_OPTERR
} GSocketError;

typedef enum {
  GSOCK_INPUT  = 0,
  GSOCK_OUTPUT = 1,
  GSOCK_CONNECTION = 2,
  GSOCK_LOST = 3,
  GSOCK_MAX_EVENT = 4
} GSocketEvent;

enum {
  GSOCK_INPUT_FLAG = 1 << GSOCK_INPUT,
  GSOCK_OUTPUT_FLAG = 1 << GSOCK_OUTPUT,
  GSOCK_CONNECTION_FLAG = 1 << GSOCK_CONNECTION,
  GSOCK_LOST_FLAG = 1 << GSOCK_LOST
};

typedef int GSocketEventFlags;
typedef void ( *GSocketCallback )( GSocket *socket, GSocketEvent event,char *cdata );

class GSocketGUIFunctionsTable {
  public:
    virtual ~GSocketGUIFunctionsTable() { }
    virtual bool OnInit() = 0;
    virtual void OnExit() = 0;
    virtual bool CanUseEventLoop() = 0;
    virtual bool Init_Socket( GSocket *socket ) = 0;
    virtual void Destroy_Socket( GSocket *socket ) = 0;
    virtual void Install_Callback(GSocket *socket, GSocketEvent event) = 0;
    virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event) = 0;
    virtual void Enable_Events( GSocket *socket ) = 0;
    virtual void Disable_Events( GSocket *socket ) = 0;
};

void GSocket_SetGUIFunctions( GSocketGUIFunctionsTable *guifunc );

int GSocket_Init( void );
void GSocket_Cleanup( void );
GSocket *GSocket_new( void );
GAddress *GAddress_new( void );
GAddress *GAddress_copy( GAddress *address );
void GAddress_destroy( GAddress *address );

void GAddress_SetFamily( GAddress *address, GAddressType type );
GAddressType GAddress_GetFamily( GAddress *address );
GSocketError GAddress_INET_SetHostName( GAddress *address, const char *hostname );
GSocketError GAddress_INET_SetAnyAddress( GAddress *address );
GSocketError GAddress_INET_SetHostAddress( GAddress *address, unsigned long hostaddr );
GSocketError GAddress_INET_SetPortName( GAddress *address, const char *port, const char *protocol );
GSocketError GAddress_INET_SetPort( GAddress *address, unsigned short port );
GSocketError GAddress_INET_GetHostName( GAddress *address, char *hostname, size_t sbuf );
unsigned long GAddress_INET_GetHostAddress( GAddress *address );
unsigned short GAddress_INET_GetPort( GAddress *address );
GSocketError GAddress_UNIX_SetPath( GAddress *address, const char *path );
GSocketError GAddress_UNIX_GetPath( GAddress *address, char *path, size_t sbuf );

#ifdef __cplusplus
}
#endif /* __cplusplus */

#include "wx/unix/gsockunx.h"

#endif    /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */

#endif    /* __GSOCKET_H */
